package com.xtayfjpk.security.jsse;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.KeyStore;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

import org.junit.Test;

public class SSLSocketTest {
	
	@Test
	public void testRunServer() throws Exception {
		//获取SSL上下文
		SSLContext context = SSLContext.getInstance("SSL");
		String keyStorePassword = "password";
		//获取服务端KeyStore
		KeyStore serverKeys = getKeyStore("serverKeys", "jks", keyStorePassword);
		//获取KeyManagerFactory
		KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
		String privateKeyPassword = "password";
		//初始化KeyManagerFactory
		keyManagerFactory.init(serverKeys, privateKeyPassword.toCharArray());
		
		//获取TrustManagerFactory
		TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
		String trustStorePassword = "password";
		//获取服务端信任KeyStore
		KeyStore serverTrustKeys = getKeyStore("serverTrust", "jks", trustStorePassword);
		//初始化TrustManagerFactory
		trustManagerFactory.init(serverTrustKeys);
		//初始化SSL上下文
		context.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
		
		//使用SSL上下文获取SSLServerSocketFactory
		SSLServerSocketFactory ssf = (SSLServerSocketFactory) context.getServerSocketFactory();
		//使用SSLServerSocketFactory创建出SSLServerSocket，并监听指定端口
		SSLServerSocket serverSocket = (SSLServerSocket) ssf.createServerSocket(9999);
		//设置需要对客户端进行认证
		serverSocket.setNeedClientAuth(true);
		
		while(true) {
			try {
				//等待客户端连接
				SSLSocket socket = (SSLSocket) serverSocket.accept();
				InputStream in = socket.getInputStream();
				
				byte[] buf = new byte[1024];
				int len = in.read(buf);
				System.out.println(new String(buf, 0, len));
				in.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
			
	}
	
	@Test
	public void testRunClient() throws Exception {
		SSLContext context = SSLContext.getInstance("SSL");
		String keyStorePassword = "password";
		KeyStore clientKeys = SimpleSSLServer.getKeyStore("clientKeys", "jks", keyStorePassword);
		KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
		String privateKeyPassword = "xtayfjpk";
		keyManagerFactory.init(clientKeys, privateKeyPassword.toCharArray());
		
		TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
		String trustStorePassword = "password";
		KeyStore serverTrustKeys = getKeyStore("clientTrust", "jks", trustStorePassword);
		trustManagerFactory.init(serverTrustKeys);
		context.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
		
		//使用SSL上下文创建SSLSocket
		SSLSocketFactory factory = (SSLSocketFactory) context.getSocketFactory();
		
		String host = "127.0.0.1";
		//创建SSLSocket
		SSLSocket socket = (SSLSocket) factory.createSocket(host, 9999);
		//与服务端进行通信
		OutputStream outputStream = socket.getOutputStream();
		outputStream.write("xtayfjpk".getBytes());
		outputStream.flush();
		outputStream.close();
		socket.close();
		
	}
	
	public static KeyStore getKeyStore(String keyStorePath, String type, String keyStorePassword) throws Exception {
		KeyStore keyStore = KeyStore.getInstance(type);
		FileInputStream in = new FileInputStream(keyStorePath);
		keyStore.load(in, keyStorePassword.toCharArray());
		in.close();
		return keyStore;
	}
}
